#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STACK_SIZE (1024)

typedef struct TrafficState
{
    int TrafficTimer[4];
    int LightState[4][3];
    int TimerLength[4][3];

    bool Changed;

    int uid; // 添加 uid 字符串常量
} TrafficState;

int GetCurrentColor(TrafficState *ins, int direction)

{
    for (int i = 0; i < 3; i++)
    {
        if (ins->LightState[direction][i])
        {
            return i;
        }
    }
    return 0; // 默认返回红灯
}

int GetNextColor(TrafficState *ins, int currentColor)
{
    if (currentColor == 0)
    {
        return 2;
    }
    else if (currentColor == 2)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

void Init(TrafficState *ins, int id)
{
    // 初始化代码
    for (int i = 0; i < 4; i+=2)
    {
        ins->LightState[i][0] = true;
        ins->LightState[i][1] = false;
        ins->LightState[i][2] = false;
        ins->TimerLength[i][0] = 59;
        ins->TimerLength[i][1] = 3;
        ins->TimerLength[i][2] = 55;
        ins->TrafficTimer[i] = ins->TimerLength[i][0];
    }
    for (int i = 1; i < 4; i+=2)
    {
        ins->LightState[i][0] = false;
        ins->LightState[i][1] = false;
        ins->LightState[i][2] = true;
        ins->TimerLength[i][0] = 59;
        ins->TimerLength[i][1] = 3;
        ins->TimerLength[i][2] = 55;
        ins->TrafficTimer[i] = ins->TimerLength[i][2];
    }
    ins->Changed = 0;
    ins->uid = id;
}

void Update(TrafficState *ins, int direction)
{
    if (ins->TrafficTimer[direction] > 0)
    {
        ins->TrafficTimer[direction]--;
    }
    else
    {
        int currentColor = GetCurrentColor(ins, direction);
        int nextColor = GetNextColor(ins, currentColor);

        ins->LightState[direction][currentColor] = 0;
        ins->LightState[direction][nextColor] = 1;

        ins->TrafficTimer[direction] = ins->TimerLength[direction][nextColor];

        ins->Changed = true;
    }
}

void UpdateAll(TrafficState *ins)
{
    for (int i = 0; i < 4; i++)
    {
        Update(ins, i);
    }
}

void Serialize(TrafficState *ins, char *data)
{
    sprintf(data, "%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d\n",
            ins->TrafficTimer[0],
            ins->TrafficTimer[1],
            ins->TrafficTimer[2],
            ins->TrafficTimer[3],
            ins->LightState[0][0],
            ins->LightState[0][1],
            ins->LightState[0][2],
            ins->LightState[1][0],
            ins->LightState[1][1],
            ins->LightState[1][2],
            ins->LightState[2][0],
            ins->LightState[2][1],
            ins->LightState[2][2],
            ins->LightState[3][0],
            ins->LightState[3][1],
            ins->LightState[3][2],
            ins->TimerLength[0][0],
            ins->TimerLength[0][1],
            ins->TimerLength[0][2],
            ins->TimerLength[1][0],
            ins->TimerLength[1][1],
            ins->TimerLength[1][2],
            ins->TimerLength[2][0],
            ins->TimerLength[2][1],
            ins->TimerLength[2][2],
            ins->TimerLength[3][0],
            ins->TimerLength[3][1],
            ins->TimerLength[3][2]);
}

void Deserialize(TrafficState *ins, char *serializedData)
{
    sscanf(serializedData, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
           &ins->TrafficTimer[0],
           &ins->TrafficTimer[1],
           &ins->TrafficTimer[2],
           &ins->TrafficTimer[3],
           &ins->LightState[0][0],
           &ins->LightState[0][1],
           &ins->LightState[0][2],
           &ins->LightState[1][0],
           &ins->LightState[1][1],
           &ins->LightState[1][2],
           &ins->LightState[2][0],
           &ins->LightState[2][1],
           &ins->LightState[2][2],
           &ins->LightState[3][0],
           &ins->LightState[3][1],
           &ins->LightState[3][2],
           &ins->TimerLength[0][0],
           &ins->TimerLength[0][1],
           &ins->TimerLength[0][2],
           &ins->TimerLength[1][0],
           &ins->TimerLength[1][1],
           &ins->TimerLength[1][2],
           &ins->TimerLength[2][0],
           &ins->TimerLength[2][1],
           &ins->TimerLength[2][2],
           &ins->TimerLength[3][0],
           &ins->TimerLength[3][1],
           &ins->TimerLength[3][2]);
}